<script lang="ts" setup>
import type { FormInstance, InputInstance } from '@arco-design/web-vue'
import { Message } from '@arco-design/web-vue'
import { nextTick } from 'vue'
import AvatarUpload from '../student/components/AvatarUpload.vue'
import ConflictTip from './components/ConflictTip.vue'
import ArrangeTemplatePicker from '@/views/system/business/rules/ArrangeTemplate/ArrangeTemplatePicker.vue'
import TimeTemplatePicker from '@/views/system/business/rules/TimeTemplate/TimeTemplatePicker.vue'
import ArrangeCalendar from '@/views/system/business/rules/ArrangeTemplate/components/ArrangeCalendar.vue'
import { useConfirm, useDictLabel, useForm } from '@/hooks'
import { ArrangeTemplateApi, ClassInfoApi, TimeTemplateApi } from '@/apis'
import { calculateGradeLimitLegacy } from '@/utils/edu'

defineOptions({
  name: 'ClassCreate',
})
const router = useRouter()
const route = useRoute()
const arrangePickerRef = ref<InstanceType<typeof ArrangeTemplatePicker>>()
const timePickerRef = ref<InstanceType<typeof TimeTemplatePicker>>()

const { form } = useForm({
  name: undefined,
  classYear: undefined,
  grade: undefined,
  subject: undefined,
  classCategory: 1,
  admissionYearLimit: new Date().getFullYear().toString(),
  classTypeId: undefined,
  classLevelLimit: undefined,
  campusId: undefined,
  classroomId: undefined,
  leadTeacherId: undefined,
  planStudentCount: undefined,
  arrangeTemplateId: undefined,
  timeTemplateId: undefined,
  lessonChangeLimit: 3,
  totalPrice: undefined,
  unitPrice: undefined,
  saleStatus: 0,
  term: undefined,
  image: undefined,
  description: undefined,
  prevClassId: undefined,
  renewalStartTime: undefined,
  renewalEndTime: undefined,
  enrollStartTime: undefined,
  lessonHourFactor: 3.0,
  salePerformanceFactor: 1.0,

  importPrevStudent: true,
})

const formRef = ref<FormInstance>()
const rules: FormInstance['rules'] = {
  name: [{ required: true, message: '请输入班级名称' }],
  subject: [{ required: true, message: '请选择科目' }],
  classCategory: [{ required: true, message: '请选择班级类别' }],
  classTypeId: [{ required: true, message: '请选择班型' }],
  classroomId: [{ required: true, message: '请选择教室' }],
  leadTeacherId: [{ required: true, message: '请选择主讲老师' }],
  planStudentCount: [{ required: true, message: '请输入计划招生人数' }],
  lessonChangeLimit: [{ required: true, message: '请选择调课次数限制' }],
  admissionYearLimit: [{ required: true, message: '请选择入学年份限制' }],
  totalPrice: [{ required: true, message: '请输入总价' }],
  unitPrice: [{ required: true, message: '请输入单价' }],
  lessonHourFactor: [{ required: true, min: 0, message: '请输入课时业绩系数' }],
  salePerformanceFactor: [{ required: true, min: 0, message: '请输入销售业绩系数' }],
}

// 班级名称
const nameRef = ref<InputInstance>()
const nameEditMode = ref<boolean>(false)
const changeEditStatus = () => {
  nameEditMode.value = !nameEditMode.value
  if (nameEditMode.value) {
    nextTick(() => {
      nameRef.value?.focus()
    })
  }
}

// 选课权限
const gradeLimit = computed(() => {
  return calculateGradeLimitLegacy(form.admissionYearLimit)
})

// 排课期段
const selectedArrangeTemplate = ref()
const onArrangeTemplateSelected = (record) => {
  form.arrangeTemplateId = record.id
  form.classYear = record.classYear
  form.grade = record.grade
  form.term = record.term
  selectedArrangeTemplate.value = record
}
const getArrangeTemplateDetail = async (id: string) => {
  const res = await ArrangeTemplateApi.getArrangeTemplateDetail(id)
  onArrangeTemplateSelected(res)
}

// 排课时间段
const selectedTimeTemplate = ref()
const onTimeTemplateSelected = (record) => {
  form.timeTemplateId = record.id
  selectedTimeTemplate.value = record
}
const getTimeTemplateDetail = async (id: string) => {
  const res = await TimeTemplateApi.detail(id)
  onTimeTemplateSelected(res)
}

// 排课日历
const calendarRef = ref<InstanceType<typeof ArrangeCalendar>>()
const lessonList = ref<any[]>([])

// 提交保存
const createClass = async () => {
  try {
    await ClassInfoApi.createClass(form)
    Message.success('班级创建成功')
    router.back()
  } catch (err) {
    console.warn('创建班级失败: ', err)
  }
}

const onSave = async () => {
  const isInvalid = await formRef.value?.validate()
  if (isInvalid) {
    return false
  }
  if (!form.name) {
    return Message.error('请输入班级名称')
  }
  if (!form.timeTemplateId || !form.arrangeTemplateId || lessonList.value.length === 0) {
    return Message.error('请先生成排课信息')
  }
  const hasConflict = lessonList.value.find(item => !!item.conflictInfo)
  if (hasConflict) {
    useConfirm(async () => {
      createClass()
    }, undefined, {
      content: '存在课次冲突，确认继续创建吗？',
      showModal: true,
    })
  } else {
    createClass()
  }
}

const loading = ref<boolean>(false)
const getDetail = async (id: string) => {
  loading.value = true
  const res = await ClassInfoApi.getClassDetail(id)
  for (const key in form) {
    form[key] = res?.[key]
  }
  form.admissionYearLimit = `${form.admissionYearLimit}`
  form.classYear = `${form.classYear}`
  getTimeTemplateDetail(form.timeTemplateId)
  getArrangeTemplateDetail(form.arrangeTemplateId)
  if (route.query.isRenewal) { // 续报
    form.prevClassId = route.query.id
  }
  loading.value = false
}

// 预排课
const scheduleLoading = ref(false)
const getClassShecdule = async () => {
  scheduleLoading.value = true
  try {
    const req: ClassInfoApi.ClassScheduleReq = {
      leadTeacherId: form.leadTeacherId,
      campusId: form.campusId,
      classroomId: form.classroomId,
      arrangeTemplateId: form.arrangeTemplateId,
      timeTemplateId: form.timeTemplateId,
    }
    const classScheduleList = await ClassInfoApi.generateShecdule(req)
    lessonList.value = (classScheduleList || []).map((item: any) => {
      return {
        lessonStartTime: item.lessonStartTime.split(' ')[1],
        lessonEndTime: item.lessonEndTime.split(' ')[1],
        lessonDate: new Date(item.lessonDate),
        lessonIndex: item.lessonIndex,
        conflictInfo: item.conflictInfo,
      }
    })
  } finally {
    scheduleLoading.value = false
  }
}

// 自动排课
watchEffect(() => {
  if (form.arrangeTemplateId && form.timeTemplateId && form.classroomId && form.leadTeacherId) {
    getClassShecdule()
  }
})

// 班型名称
const classTypeName = ref('')
const onClassTypeSelect = (item) => {
  classTypeName.value = item.name
  form.classLevelLimit = item.level
}

// 班级名称
watchEffect(() => {
  if (selectedArrangeTemplate.value && selectedTimeTemplate.value && form.subject && classTypeName.value) {
    form.name = `${selectedArrangeTemplate.value.classYear}${useDictLabel('TermEnum', form.term)}${useDictLabel('Grade', form.grade)}${useDictLabel('Subject', form.subject)}${classTypeName.value}(${selectedArrangeTemplate.value.name}${selectedTimeTemplate.value.name})`
  } else {
    form.name = ''
  }
})

onMounted(() => {
  if (route.query.id) {
    getDetail(route.query.id as string)
  }
})
</script>

<template>
  <a-spin class="w-full" :loading="loading">
    <ProPage>
      <template #title>
        <a-page-header title="创建班级" @back="router.back()">
          <template #subtitle>
            <a-space>
              <a-input ref="nameRef" v-model.trim="form.name" class="name-input mr-2 w-520px!" size="large" placeholder="自动生成班级名称(年份+学期+年级+科目+班型+期段)" :disabled="!nameEditMode">
                <template #append>
                  <a-link class="h-full w-44px flex-row-center-center" @click="changeEditStatus">
                    <span v-if="nameEditMode" class="font-400">保存</span>
                    <icon-edit v-else />
                  </a-link>
                </template>
              </a-input>
            </a-space>
          </template>
          <template #extra>
            <a-space>
              <a-button type="primary" size="small" @click="onSave">
                <template #icon>
                  <icon-save />
                </template>
                提交
              </a-button>
            </a-space>
          </template>
        </a-page-header>
      </template>
      <div class="fixed">
        <a-anchor :change-hash="false" boundary="start">
          <a-anchor-link href="#basic">
            基本信息
          </a-anchor-link>
          <a-anchor-link href="#permission">
            班级权限
          </a-anchor-link>
          <a-anchor-link href="#enrollment">
            招生报名
          </a-anchor-link>
          <a-anchor-link href="#schedule">
            排课信息
          </a-anchor-link>
        </a-anchor>
      </div>
      <div class="content ml-2 flex-col-start-center">
        <a-form ref="formRef" :model="form" :rules="rules" layout="vertical" style="width: 85%;">
          <a-card id="basic" title="基础信息" class="section">
            <a-alert type="warning" class="mb" closable>
              年份、年级、上课时间等信息在<span class="font-600">排课信息</span>中设置
            </a-alert>
            <a-row :gutter="40">
              <a-col :span="8">
                <a-form-item label="类别" field="classCategory">
                  <DictSelect v-model="form.classCategory" type="button" code="ClassCategoryEnum" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="科目" field="subject">
                  <DictSelect v-model="form.subject" type="select" code="Subject" placeholder="请选择科目" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="上架状态" tooltip="下架状态将不会展示给家长端">
                  <DictSelect v-model="form.saleStatus" type="button" code="SaleStatusEnum" />
                </a-form-item>
              </a-col>
            </a-row>

            <a-row :gutter="40">
              <a-col :span="8">
                <a-form-item label="限制调课次数" field="lessonChangeLimit" tooltip="允许学生可调课次数，0代表不限次数">
                  <a-input-number v-model="form.lessonChangeLimit" :min="0" placeholder="请输入限制调课次数">
                    <template #append>
                      次
                    </template>
                  </a-input-number>
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="课时业绩系数" field="lessonHourFactor" tooltip="用于计算老师业绩，一节课业绩=1*课时业绩系数">
                  <a-input-number v-model="form.lessonHourFactor" mode="button" :step="0.1" :min="0" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="销售业绩系数" field="salePerformanceFactor" tooltip="用于计算课程顾问业绩，一次有效报名业绩=1*销售业绩系数">
                  <a-input-number v-model="form.salePerformanceFactor" mode="button" :step="0.1" :min="0" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="展示图片" field="image">
                  <AvatarUpload v-model="form.image" :width="60" :height="40" type="button" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="前序班级" field="prevClassId" tooltip="当前班级为前序班级的续报班级">
                  <ClassSelect v-model="form.prevClassId" />
                </a-form-item>
              </a-col>
              <a-col :span="6">
                <a-form-item field="importPrevStudent" label="导入前序班级学生">
                  <a-checkbox v-model="form.importPrevStudent">
                    立即导入
                  </a-checkbox>
                </a-form-item>
              </a-col>
              <a-col :span="24">
                <a-form-item label="课程介绍">
                  <a-textarea v-model.trim="form.description" placeholder="请输入课程介绍" allow-clear :max-length="900" show-word-limit />
                </a-form-item>
              </a-col>
            </a-row>
          </a-card>
          <a-card id="permission" title="班级权限" class="section">
            <a-alert v-if="form.classTypeId" type="warning" class="mb">
              <span>仅允许<span class="font-600">{{ gradeLimit }}</span>且拥有<span class="font-600">{{ classTypeName }}及以上权限</span>的学生报名</span>
            </a-alert>
            <a-row :gutter="40">
              <a-col :span="8">
                <a-form-item label="班型" field="classTypeId">
                  <ClassTypeSelect v-model="form.classTypeId" @select="onClassTypeSelect" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="入学年份限制" field="admissionYearLimit" tooltip="入学年份要求，超过当年则不限制">
                  <a-year-picker v-model="form.admissionYearLimit" placeholder="请选择" />
                </a-form-item>
              </a-col>
            </a-row>
          </a-card>
          <a-card id="enrollment" title="招生报名" class="section">
            <a-alert v-if="form.enrollStartTime && form.renewalStartTime && form.renewalEndTime" :show-icon="false" class="mb">
              <a-timeline direction="horizontal" mode="bottom" label-position="same">
                <a-timeline-item :label="form.renewalStartTime" dot-color="#52C419">
                  续报期开始，允许前序在读学员提前报名
                </a-timeline-item>
                <a-timeline-item :label="form.renewalEndTime" dot-color="#F5222D">
                  续报期结束，不允许报名，仅允许调课转班
                </a-timeline-item>
                <a-timeline-item :label="form.enrollStartTime">
                  开放报名，允许所有人报名
                </a-timeline-item>
              </a-timeline>
            </a-alert>
            <a-row :gutter="40">
              <a-col :span="12">
                <a-form-item label="续报期" tooltip="续报期开始后允许当前在读学员提前报名，续报期结束后不允许提前报名，但允许调课转班">
                  <RangePicker
                    v-model:from="form.renewalStartTime" v-model:to="form.renewalEndTime" show-time format="YYYY-MM-DD HH:mm" :placeholder="['续报开始时间', '续报结束时间']" :time-picker-props="{
                      step: {
                        minute: 10,
                      },
                    }"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="开放报名时间" tooltip="该时间后允许所有人报名">
                  <a-date-picker
                    v-model="form.enrollStartTime"
                    class="w-full"
                    show-time
                    format="YYYY-MM-DD HH:mm"
                    placeholder="开放报名时间"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="计划招生" field="planStudentCount">
                  <a-input-number v-model="form.planStudentCount" :min="0" placeholder="请输入计划招生人数">
                    <template #prefix>
                      <icon-user />
                    </template>
                    <template #append>
                      人
                    </template>
                  </a-input-number>
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="单价" field="unitPrice">
                  <a-input-number v-model="form.unitPrice" :min="0" placeholder="请输入单价" :hide-button="true">
                    <template #append>
                      元
                    </template>
                  </a-input-number>
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="总价" field="totalPrice">
                  <a-input-number v-model="form.totalPrice" :min="0" placeholder="请输入总价" :hide-button="true">
                    <template #append>
                      元
                    </template>
                  </a-input-number>
                </a-form-item>
              </a-col>
            </a-row>
          </a-card>
          <a-card id="schedule" title="排课信息" class="section">
            <a-alert v-if="!lessonList || lessonList.length === 0" type="warning" class="mb" closable>
              <span>填写下列信息后，系统将自动排课并校验冲突</span>
            </a-alert>
            <a-row :gutter="40">
              <a-col :span="8">
                <a-form-item label="教室" field="classroomId">
                  <ClassroomCascader v-model:campus-id="form.campusId" v-model:classroom-id="form.classroomId" placeholder="请选择教室" />
                  <!-- <ClassroomSelect v-model="form.classroomId" placeholder="请选择教室" @select="onClassroomSelect" /> -->
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="主讲老师" field="leadTeacherId">
                  <EmployeeSelect v-model="form.leadTeacherId" type="LEAD_TEACHER" placeholder="请选择老师" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="辅导老师">
                  <EmployeeSelect v-model="form.assistTeacherId" type="ASSIST_TEACHER" placeholder="请选择老师" />
                </a-form-item>
              </a-col>
            </a-row>
            <a-space class="mb" size="large">
              <a-button type="primary" @click="arrangePickerRef?.open()">
                上课期段
                <span v-if="selectedArrangeTemplate" class="mr-1">:{{ selectedArrangeTemplate.name }}</span>
                <icon-down />
              </a-button>
              <a-button type="primary" @click="timePickerRef?.open()">
                上课时间段
                <span v-if="selectedTimeTemplate" class="mr-1">:{{ selectedTimeTemplate.name }}</span>
                <icon-down />
              </a-button>
              <a-alert v-if="selectedArrangeTemplate">
                <a-space>
                  <span class="text-black">{{ selectedArrangeTemplate.classYear }}年 · <DictLabel v-model="selectedArrangeTemplate.term" code="TermEnum" /> · <DictLabel v-model="selectedArrangeTemplate.grade" code="Grade" /></span>
                  <span class="text-13px text-gray-6">
                    {{ selectedArrangeTemplate.startDate }}~{{ selectedArrangeTemplate.endDate }}
                  </span>
                  <span v-if="selectedTimeTemplate" class="text-13px text-gray-6">
                    {{ selectedTimeTemplate.startTime }} - {{ selectedTimeTemplate.endTime }}
                  </span>
                </a-space>
              </a-alert>
            </a-space>

            <div v-if="scheduleLoading" class="my flex-row-center-center">
              <a-spin dot tip="课表生成中..." />
            </div>
            <ArrangeCalendar
              v-if="lessonList && lessonList.length > 0"
              ref="calendarRef"
              v-model="lessonList"
              select-mode="select"
              :disabled="true"
              :show-dot="false"
              :readonly="true"
            >
              <template #extra="{ item }">
                <div v-if="item.conflictInfo" class="icon">
                  <a-popover title="冲突课次">
                    <a-tag color="red">
                      <template #icon>
                        <icon-exclamation-circle-fill />
                      </template>
                      冲突
                    </a-tag>
                    <template #content>
                      <ConflictTip :data="item.conflictInfo" />
                    </template>
                  </a-popover>
                </div>
                <div v-else class="icon color-green">
                  <icon-check-circle-fill />
                </div>
              </template>
            </ArrangeCalendar>
          </a-card>
        </a-form>
        <ArrangeTemplatePicker ref="arrangePickerRef" @select="onArrangeTemplateSelected" />
        <TimeTemplatePicker ref="timePickerRef" @select="onTimeTemplateSelected" />
      </div>
    </ProPage>
  </a-spin>
</template>

<style lang="less" scoped>
.content {
  :deep(.arco-card-header) {
    position: relative;
    z-index: 1;
  }
}
:deep(.arco-card-header) {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #fff;
  padding: 10px 0;
}

.name-input {
  :deep(.arco-btn-size-medium) {
    padding: 0;
  }

  :deep(.arco-input-append) {
    padding: 0;
  }
}
</style>
